package com.membership.cloud.web.model;

import com.membership.cloud.exception.ServerTechnicalException;
import com.membership.cloud.jpa.domain.NameDescPersistable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Persistable;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hiephn on 2014/07/12.
 */
public abstract class AbstractDataPageResponse<ENT extends Persistable<Integer>, RES extends IDResponse<ENT>>
        implements DataPageResponse<ENT, RES> {
    protected int pageNumber;
    protected int totalPages;
    protected long totalElements;
    protected int pageSize;
    protected int numberOfElements;
    protected List<RES> dataList;

    public int getPageNumber() {
        return pageNumber;
    }

    public void setPageNumber(int pageNumber) {
        this.pageNumber = pageNumber;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }

    public long getTotalElements() {
        return totalElements;
    }

    public void setTotalElements(long totalElements) {
        this.totalElements = totalElements;
    }

    public int getPageSize() {
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getNumberOfElements() {
        return numberOfElements;
    }

    public void setNumberOfElements(int numberOfElements) {
        this.numberOfElements = numberOfElements;
    }

    public List<RES> getDataList() {
        return dataList;
    }

    public void setDataList(List<RES> dataList) {
        this.dataList = dataList;
    }

    @Override
    public void from(List<ENT> list, Class<RES> responseClass)
            throws ServerTechnicalException {
        this.dataListFrom(list, responseClass);
        this.setPageNumber(0);
        this.setTotalElements(list.size());
        this.setTotalPages(1);
        this.setNumberOfElements(list.size());
        this.setPageSize(list.size());
    }

    @Override
    public void from(Page<ENT> page, Class<RES> responseClass)
            throws ServerTechnicalException {
        this.dataListFrom(page, responseClass);
        this.setPageNumber(page.getNumber());
        this.setTotalElements(page.getTotalElements());
        this.setTotalPages(page.getTotalPages());
        this.setNumberOfElements(page.getNumberOfElements());
        this.setPageSize(page.getSize());
    }

    @Override
    public void from(ENT entity, Class<RES> responseClass)
            throws ServerTechnicalException {
        try {
            RES response = responseClass.newInstance();
            response.setData(entity);
            this.dataList = new ArrayList<>(1);
            this.dataList.add(response);
            this.setPageNumber(0);
            this.setTotalElements(1);
            this.setTotalPages(1);
            this.setNumberOfElements(1);
            this.setPageSize(1);
        } catch (InstantiationException | IllegalAccessException e) {
            throw new ServerTechnicalException("Cannot generate response", e);
        }
    }

    @Override
    public void dataListFrom(List<ENT> list, Class<RES> responseClass)
            throws ServerTechnicalException {
        if (list != null) {
            this.dataList = new ArrayList<>(list.size());
            for (ENT entity : list) {
                RES response = null;
                try {
                    response = responseClass.newInstance();
                    response.setData(entity);
                    this.dataList.add(response);
                } catch (InstantiationException | IllegalAccessException e) {
                    throw new ServerTechnicalException("Cannot generate response", e);
                }
            }
        }
    }

    @Override
    public void dataListFrom(Page<ENT> page, Class<RES> responseClass)
            throws ServerTechnicalException {
        if (page != null) {
            this.dataList = new ArrayList<>(page.getContent().size());
            for (ENT entity : page) {
                try {
                    RES response = responseClass.newInstance();
                    response.setData(entity);
                    this.dataList.add(response);
                } catch (InstantiationException | IllegalAccessException e) {
                    throw new ServerTechnicalException("Cannot generate response", e);
                }
            }
        }
    }
}
